package org.hawk.gwt.ppc;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.LinkedList;
import java.util.List;

import org.hawk.gwt.ppc.scanner.SourcesLoader;

/**
 * This class loader is used by GWT compiler to resolve java sources. The main
 * idea is to load processed resources and classes prior to the not processed
 * ones. In this scenario when class loader looks for the resource with specific
 * name, it search in processed files folder first. If resource wasn't found
 * there - the default resource will be loaded.
 * 
 * @author alex.bereznevatiy@gmail.com
 */
public final class ProcessedSourcesLoader extends URLClassLoader {
	private static final String LANG_MODULE_SUPERSOURCE = "org/hawk/gwt/ppc/reflect/emul/";
	private SourcesLoader loader;

	ProcessedSourcesLoader(SourcesLoader loader) {
		super(getUrls(loader), (ClassLoader) null);
		this.loader = loader;
	}
	
	private static URL[] getUrls(SourcesLoader loader) {
		List<URL> urls = new LinkedList<URL>();
		urls.add(loader.toUrl());
		URLClassLoader classpath = (URLClassLoader) ClassLoader
				.getSystemClassLoader();
		for (URL url : classpath.getURLs()) {
			urls.add(url);
		}
		return urls.toArray(new URL[0]);
	}

	@Override
	public URL getResource(String name) {
		URL url = loader.getResource(name);
		if (url != null) {
			return url;
		}
		if (name.startsWith("java/lang/")) {
			return getLangModuleResource(name);
		}
		return super.getResource(name);
	}

	private URL getLangModuleResource(String name) {
		return getClass().getClassLoader().getResource(
				LANG_MODULE_SUPERSOURCE + name);
	}
}
